package com.macro.mall.portal.service.impl;

import com.alibaba.fastjson.JSON;
import com.macro.mall.common.service.RedisService;
import com.macro.mall.mapper.PmsSkuStockMapper;
import com.macro.mall.model.*;
import com.macro.mall.portal.dao.PortalProductDao;
import com.macro.mall.portal.dao.PortalSkuStockDao;
import com.macro.mall.portal.domain.CartPromotionItem;
import com.macro.mall.portal.domain.CombinedPmsProduct;
import com.macro.mall.portal.domain.PromotionProduct;
import com.macro.mall.portal.service.OmsPromotionService;
import com.macro.mall.portal.service.PmsMemberPriceService;
import com.macro.mall.portal.service.UmsMemberService;
import com.quyum.mall.market.config.RedisKey;
import com.quyum.mall.market.entity.MarketSmsRound;
import com.quyum.mall.market.entity.MarketSmsRoundProduct;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * Created by macro on 2018/8/27.
 * 促销管理Service实现类
 */
@Service
public class OmsPromotionServiceImpl implements OmsPromotionService {
    Logger logger = LoggerFactory.getLogger(OmsPromotionServiceImpl.class);
    @Autowired
    private PortalProductDao portalProductDao;
    @Autowired
    private UmsMemberService umsMemberService;
    @Autowired
    private PmsSkuStockMapper pmsSkuStockMapper;
    @Autowired
    private PmsMemberPriceService memberPriceService;
    @Autowired
    private PortalSkuStockDao skuStockDao;
    @Autowired
    private RedisService redisService;

    @Override
    public List<CartPromotionItem> calcCartPromotion(Long memberId, List<OmsCartItem> cartItemList, Long storeId) {
        logger.info("calcCartPromotion-------------cartItemList---------------------"+ JSON.toJSON(cartItemList));
        //1.先根据productId对CartItem进行分组，以spu为单位进行计算优惠
        Map<Long, List<OmsCartItem>> productCartMap = groupCartItemBySpu(cartItemList);
        //2.查询所有商品的优惠相关信息
        List<PromotionProduct> promotionProductList = getPromotionProductList(memberId, cartItemList, storeId);
        //3.根据商品促销类型计算商品促销优惠价格
        List<CartPromotionItem> cartPromotionItemList = new ArrayList<>();
        UmsMember currentMember = umsMemberService.getById(memberId);
        for (Map.Entry<Long, List<OmsCartItem>> entry : productCartMap.entrySet()) {
            Long skuId = entry.getKey();
            PromotionProduct promotionProduct = getPromotionProductById(skuId, promotionProductList);
            logger.info("calcCartPromotion-------------promotionProduct---------------------"+ JSON.toJSON(promotionProduct));
            List<OmsCartItem> itemList = entry.getValue();
            Integer promotionType = 0;
            Integer type = 0;
            if(promotionProduct!= null){
                type = promotionProduct.getType();
            }
            if (currentMember.getMemberLevel() != null && !currentMember.getMemberLevel().equals(1) && currentMember.getMemberLevelEndTime().after(new Date())) {
                promotionType = 2;
            }
            if (promotionType == 2) {
                //会员价
                for (OmsCartItem item : itemList) {
                    CartPromotionItem cartPromotionItem = new CartPromotionItem();
                    BeanUtils.copyProperties(item, cartPromotionItem);
                    //(商品原价/总价)*满减金额
                    PmsSkuStock skuStock = getOriginalPrice(promotionProduct, item.getProductSkuId());
                    String skuKey = new StringBuffer(RedisKey.ROUND_SKU_STOCK_KEY).append(item.getProductId()).append("_").append(item.getProductSkuId()).toString();
                    Object o = this.redisService.get(skuKey);
                    MarketSmsRoundProduct marketSmsRoundProduct=null;
                    if(o!=null){
                        marketSmsRoundProduct= (MarketSmsRoundProduct)o ;
                    }
                    BigDecimal originalPrice = skuStock.getPrice();
                    BigDecimal memberPrice = this.memberPriceService.getMemberPrice(item.getProductSkuId(), storeId);
                    if (memberPrice == null || type == 1 || memberPrice.compareTo(BigDecimal.ZERO) <=  0) {
                        //组合商品没有会员价
                        memberPrice = originalPrice;
                    }
                    BigDecimal reduceAmount = BigDecimal.ZERO;
                    String activityType = "会员价";
                    if (marketSmsRoundProduct!=null){
                        cartPromotionItem.setRoundId(marketSmsRoundProduct.getRoundId());
                        MarketSmsRound smsRound = (MarketSmsRound)this.redisService.get(RedisKey.ROUND_STARTING_KEY + marketSmsRoundProduct.getRoundId());
                        cartPromotionItem.setEndTime(smsRound.getEndTime());
                        cartPromotionItem.setRoundId(smsRound.getId());
                        reduceAmount = originalPrice.subtract(marketSmsRoundProduct.getActivityPrice());
                        cartPromotionItem.setActivityPrice(marketSmsRoundProduct.getActivityPrice());
                        switch (marketSmsRoundProduct.getType()){
                            case 2:
                                activityType= "秒杀";
                                type = 2;
                                break;
                            case 3:
                                activityType= "团购";
                                type =3;
                                break;
                            case 5:
                                activityType= "闪购";
                                type = 5;
                                break;
                            default:
                                break;
                        }
                    }else{
                        reduceAmount = originalPrice.subtract(memberPrice);
                    }
                    cartPromotionItem.setPromotionMessage(activityType);
                    cartPromotionItem.setReduceAmount(reduceAmount);
                    cartPromotionItem.setMemberPrice(memberPrice);
                    cartPromotionItem.setProductSkuId(skuStock.getId());
                    cartPromotionItem.setRealStock(promotionProduct.getStock());
                    cartPromotionItem.setIntegration(promotionProduct.getGiftPoint());
                    cartPromotionItem.setGrowth(promotionProduct.getGiftGrowth());
                    cartPromotionItem.setCommissionAmount(new BigDecimal(item.getQuantity()).multiply(promotionProduct.getCommission()).multiply(originalPrice.subtract(reduceAmount)).divide(BigDecimal.TEN.multiply(BigDecimal.TEN), 2));
                    cartPromotionItem.setCombinedPmsProduct(this.getGroup(type, item.getProductSkuId()));
                    cartPromotionItem.setType(type);
                    cartPromotionItemList.add(cartPromotionItem);
                }
            } else {
                handleNoReduce(cartPromotionItemList, itemList, promotionProduct, type);
            }
        }
        return cartPromotionItemList;
    }

    /**
     * 查询所有商品的优惠相关信息
     */
    private List<PromotionProduct> getPromotionProductList(Long memberId, List<OmsCartItem> cartItemList, Long storeId) {
        List<Long> productIdList = new ArrayList<>();
        for (OmsCartItem cartItem : cartItemList) {
            productIdList.add(cartItem.getProductId());
        }
        List<Long> skuIds = cartItemList.stream().map(OmsCartItem::getProductSkuId).collect(Collectors.toList());
        List<PromotionProduct> promotionProductList = this.getPromotionProducts(memberId, skuIds, storeId);
        return promotionProductList;
    }

    /**
     * 获取商品的库存优惠信息
     *
     * @param memberId
     * @param skuIds
     * @return
     */
    private List<PromotionProduct> getPromotionProducts(Long memberId, List<Long> skuIds, Long storeId) {
//        Map<Long, Integer> map = new HashMap<>();
        List<PromotionProduct> promotionProductList = portalProductDao.getPromotionProductList(skuIds, memberId, storeId);
        //获取组合商品ids
        if (!CollectionUtils.isEmpty(promotionProductList)) {
            for (PromotionProduct goods : promotionProductList) {
                Integer count = Integer.MAX_VALUE;
                if (goods.getType() == 1) {
                    String skuKey = new StringBuffer(RedisKey.ROUND_SKU_STOCK_KEY).append(goods.getId()).append("_").append(goods.getSkuStockList().get(0).getId()).toString();
                    Object o = this.redisService.get(skuKey);
                    count = getCombinedStock(goods.getSkuStockList().get(0).getId(), memberId,o==null?0:1);
                } else {
                    List<PmsSkuStock> skuStockList = goods.getSkuStockList();
                    if (!CollectionUtils.isEmpty(skuStockList)) {
                        List<PmsSkuStock> collect = skuStockList.stream().filter(e -> e.getStock() != null).collect(Collectors.toList());
                        if(!CollectionUtils.isEmpty(collect)){
                            List<PmsSkuStock> collect1 = collect.stream().filter(e -> e.getLockStock() != null).collect(Collectors.toList());
                            if(!CollectionUtils.isEmpty(collect1)){
                                count = collect1.stream().collect(Collectors.summingInt(PmsSkuStock::getStock))
                                        - collect1.stream().collect(Collectors.summingInt(PmsSkuStock::getLockStock));
                                String skuKey = new StringBuffer(RedisKey.ROUND_SKU_STOCK_KEY).append(goods.getId()).append("_").append(goods.getSkuStockList().get(0).getId()).toString();
                                Object o = this.redisService.get(skuKey);
                                if(o!=null){
                                    count = count + collect1.stream().collect(Collectors.summingInt(PmsSkuStock::getActivityLockStock));
                                }
                            }else {
                                count = 0;
                            }
                        }else{
                            count = 0;
                        }

                    } else {
                        count = 0;
                    }
                }
                goods.setStock(count);
            }
        }
        return promotionProductList;
    }

    /**
     * 以sku为单位对购物车中商品进行分组
     */
    private Map<Long, List<OmsCartItem>> groupCartItemBySpu(List<OmsCartItem> cartItemList) {
        return cartItemList.stream().collect(Collectors.groupingBy(OmsCartItem::getProductSkuId));
    }

    /**
     * 获取满减促销消息
     */
    private String getFullReductionPromotionMessage(PmsProductFullReduction fullReduction) {
        StringBuilder sb = new StringBuilder();
        sb.append("满减优惠：");
        sb.append("满");
        sb.append(fullReduction.getFullPrice());
        sb.append("元，");
        sb.append("减");
        sb.append(fullReduction.getReducePrice());
        sb.append("元");
        return sb.toString();
    }

    /**
     * 对没满足优惠条件的商品进行处理
     */
    private void handleNoReduce(List<CartPromotionItem> cartPromotionItemList, List<OmsCartItem> itemList, PromotionProduct promotionProduct, Integer type) {
        for (OmsCartItem item : itemList) {
            PmsSkuStock skuStock = getOriginalPrice(promotionProduct, item.getProductSkuId());
            BigDecimal originalPrice = skuStock.getPrice();
            CartPromotionItem cartPromotionItem = new CartPromotionItem();
            BeanUtils.copyProperties(item, cartPromotionItem);
            String skuKey = new StringBuffer(RedisKey.ROUND_SKU_STOCK_KEY).append(item.getProductId()).append("_").append(item.getProductSkuId()).toString();
            Object o = this.redisService.get(skuKey);
            MarketSmsRoundProduct marketSmsRoundProduct=null;
            if(o!=null){
                marketSmsRoundProduct= (MarketSmsRoundProduct)o ;
            }
            BigDecimal reduceAmount = BigDecimal.ZERO;
            String activityType= "无优惠";
            if(marketSmsRoundProduct!=null){
                MarketSmsRound smsRound = (MarketSmsRound)this.redisService.get(RedisKey.ROUND_STARTING_KEY + marketSmsRoundProduct.getRoundId());
                cartPromotionItem.setEndTime(smsRound.getEndTime());
                cartPromotionItem.setRoundId(smsRound.getId());
                cartPromotionItem.setActivityPrice(marketSmsRoundProduct.getActivityPrice());
                reduceAmount = originalPrice.subtract(marketSmsRoundProduct.getActivityPrice());
                switch (marketSmsRoundProduct.getType()){
                    case 2:
                        type = 2;
                        activityType= "秒杀";
                        break;
                    case 3:
                        type =3;
                        activityType= "团购";
                        break;
                    case 5:
                        type =5;
                        activityType= "闪购";
                        break;
                    default:
                        break;
                }
            }
            cartPromotionItem.setPromotionMessage(activityType);
            cartPromotionItem.setReduceAmount(reduceAmount);
            cartPromotionItem.setProductSkuId(skuStock.getId());
            cartPromotionItem.setRealStock(promotionProduct.getStock());
            cartPromotionItem.setIntegration(promotionProduct.getGiftPoint());
            cartPromotionItem.setGrowth(promotionProduct.getGiftGrowth());
            cartPromotionItem.setCommissionAmount(new BigDecimal(item.getQuantity()).multiply(promotionProduct.getCommission()).multiply(originalPrice.subtract(reduceAmount)).divide(BigDecimal.TEN.multiply(BigDecimal.TEN), 2));
            cartPromotionItem.setCombinedPmsProduct(this.getGroup(type, item.getProductSkuId()));
            cartPromotionItem.setType(type);
            cartPromotionItemList.add(cartPromotionItem);
        }
    }

    private PmsProductFullReduction getProductFullReduction(BigDecimal totalAmount, List<PmsProductFullReduction> fullReductionList) {
        //按条件从高到低排序
        fullReductionList.sort(new Comparator<PmsProductFullReduction>() {
            @Override
            public int compare(PmsProductFullReduction o1, PmsProductFullReduction o2) {
                return o2.getFullPrice().subtract(o1.getFullPrice()).intValue();
            }
        });
        for (PmsProductFullReduction fullReduction : fullReductionList) {
            if (totalAmount.subtract(fullReduction.getFullPrice()).intValue() >= 0) {
                return fullReduction;
            }
        }
        return null;
    }

    /**
     * 获取打折优惠的促销信息
     */
    private String getLadderPromotionMessage(PmsProductLadder ladder) {
        StringBuilder sb = new StringBuilder();
        sb.append("打折优惠：");
        sb.append("满");
        sb.append(ladder.getCount());
        sb.append("件，");
        sb.append("打");
        sb.append(ladder.getDiscount().multiply(new BigDecimal(10)));
        sb.append("折");
        return sb.toString();
    }

    /**
     * 根据购买商品数量获取满足条件的打折优惠策略
     */
    private PmsProductLadder getProductLadder(int count, List<PmsProductLadder> productLadderList) {
        //按数量从大到小排序
        productLadderList.sort(new Comparator<PmsProductLadder>() {
            @Override
            public int compare(PmsProductLadder o1, PmsProductLadder o2) {
                return o2.getCount() - o1.getCount();
            }
        });
        for (PmsProductLadder productLadder : productLadderList) {
            if (count >= productLadder.getCount()) {
                return productLadder;
            }
        }
        return null;
    }

    /**
     * 获取购物车中指定商品的数量
     */
    private int getCartItemCount(List<OmsCartItem> itemList) {
        int count = 0;
        for (OmsCartItem item : itemList) {
            count += item.getQuantity();
        }
        return count;
    }

    /**
     * 获取购物车中指定商品的总价
     */
    private BigDecimal getCartItemAmount(List<OmsCartItem> itemList, List<PromotionProduct> promotionProductList) {
        BigDecimal amount = new BigDecimal(0);
        for (OmsCartItem item : itemList) {
            //计算出商品原价
            PromotionProduct promotionProduct = getPromotionProductById(item.getProductSkuId(), promotionProductList);
            PmsSkuStock skuStock = getOriginalPrice(promotionProduct, item.getProductSkuId());
            amount = amount.add(skuStock.getPrice().multiply(new BigDecimal(item.getQuantity())));
        }
        return amount;
    }

    /**
     * 获取商品的原价
     */
    private PmsSkuStock getOriginalPrice(PromotionProduct promotionProduct, Long productSkuId) {
        List<PmsSkuStock> collect = new ArrayList<>();
        if(promotionProduct.getSkuStockList()!=null){
            collect = promotionProduct.getSkuStockList().stream().filter(e -> e.getId().equals(productSkuId)).collect(Collectors.toList());
        }
        if (!CollectionUtils.isEmpty(collect)) {
            return collect.get(0);
        }
        return null;
    }

    /**
     * 根据商品id获取商品的促销信息
     */
    private PromotionProduct getPromotionProductById(Long skuId, List<PromotionProduct> promotionProductList) {
        for (PromotionProduct promotionProduct : promotionProductList) {
            if(!CollectionUtils.isEmpty(promotionProduct.getSkuStockList())){
                List<PmsSkuStock> collect = promotionProduct.getSkuStockList().stream().filter(e -> e.getId().equals(skuId)).collect(Collectors.toList());
                for (PmsSkuStock skuStock:collect) {
                    if(skuStock.getId().equals(skuId)){
                        return promotionProduct;
                    }
                }
            }
        }
        return null;
    }

    /**
     * 获取组合商品和子商品
     *
     * @param skuId
     * @return
     */
    @Override
    public List<CombinedPmsProduct> getGroup(Integer type, Long skuId) {
        if (type.equals(1)) {
            List<Long> ids = new ArrayList<>();
            ids.add(skuId);
            List<CombinedPmsProduct> combinedPmsProductList = this.skuStockDao.queryProductsByCombineParentIds(ids);
            return combinedPmsProductList.get(0).getCombinedProductList();
        } else {
            return new ArrayList<CombinedPmsProduct>();
        }
    }

    @Override
    public Integer getCombinedStock(Long productId, Long memberId,Integer type){
        List<HashMap<String, Object>> combinedStock = this.portalProductDao.getCombinedStock(productId, memberId,type);
        Integer count = Integer.MAX_VALUE;
        for (HashMap<String, Object> m : combinedStock) {
            Integer c = m.get("stock") != null ? Integer.parseInt(String.valueOf(m.get("stock"))) : 0;
            Integer num = m.get("num") != null ? Integer.parseInt(String.valueOf(m.get("num"))) : 0;
            if (c != null) {
                if (count > c / num) {
                    count = c / num;
                }
            }
        }
        return count;
    }
}
